package com.smm.controller;

import com.jn.sqlhelper.dialect.pagination.PagingResult;
import com.smm.common.Result;
import com.smm.common.ResultCode;
import com.smm.entity.User;
import com.smm.service.UserService;
import com.smm.util.JwtTokenUtil;
import com.smm.util.JwtUtils;
import io.swagger.annotations.Api;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;

@RestController
@RequestMapping("user")
@Api(value = "SMM工程", tags = "user相关接口")
public class UserController {

    private final Logger log = LoggerFactory.getLogger(UserController.class);
    @Resource
    UserService userService;

    @RequiresRoles({"admin"})
    @RequiresAuthentication
    @GetMapping("hello")
    public String hello() {
        return "<h1>hhhh</h1><br><h2>相思湖未来的湖</h2>";
    }

    @PostMapping("login")
    public Result login(HttpServletResponse response, @RequestBody User user) {
        log.info(String.valueOf(user));
        User login = userService.login(user);
        if (login.getStatus()) {
            //final String token2 = JwtTokenUtil.createJWT(login.getId(), login.getUsername(), login.getRole());
            String token = JwtUtils.buildJwtRS256(login, 3600 * 60);
            response.setHeader(JwtUtils.AUTH_HEADER_KEY, JwtUtils.TOKEN_PREFIX + token);
            // 这是Header其中一个属性向外暴露，使得他能被浏览器js读取
            response.setHeader("Access-Control-Expose-Headers", JwtUtils.AUTH_HEADER_KEY);
            return Result.SUCCESS(login);

        } else {
            return new Result(ResultCode.USER_LOGIN_ERROR);
        }
    }

    @PostMapping("login2")
    public Result login2(String username,String password, HttpServletResponse response) {
       User user= new User().setUsername(username).setPassword(password);

        try {
            UsernamePasswordToken upt = new UsernamePasswordToken(user.getUsername(), user.getPassword());
            Subject subject = SecurityUtils.getSubject();
            log.info("认证前 "+ subject.isAuthenticated());
            subject.login(upt);
            log.info("认证后"+ subject.isAuthenticated());
            String id = (String) subject.getSession().getId();
            log.info("(String) subject.getSession().getId();"+id);
            if (subject.isAuthenticated()) {
                User login = (User) subject.getPrincipal();
                String token = JwtUtils.buildJwtRS256(login, 3600 * 60);
               response.setHeader(JwtUtils.AUTH_HEADER_KEY, JwtUtils.TOKEN_PREFIX + token);
                // 这是Header其中一个属性向外暴露，使得他能被浏览器js读取
                response.setHeader("Access-Control-Expose-Headers", JwtUtils.AUTH_HEADER_KEY);
                return Result.SUCCESS(login);
            } else {
                return new Result(ResultCode.USER_NOT_EXIST);
            }

        } catch (UnknownAccountException uae) {
            log.error("USER_NOT_EXIST uae",uae);
            return new Result(ResultCode.USER_NOT_EXIST);
        } catch (IncorrectCredentialsException ice) {
            log.error("USER_NOT_EXIST ice",ice);
            return new Result(ResultCode.USER_LOGIN_ERROR);
        } catch (LockedAccountException lae) {
            log.error("USER_NOT_EXIST lae",lae);
            return new Result(ResultCode.USER_ACCOUNT_FORBIDDEN);
        } catch (ExcessiveAttemptsException eae) {
            log.error("USER_NOT_EXIST eae",eae);
            return new Result(ResultCode.USER_LOGIN_ERROR);
        } catch (AuthenticationException ae) {
            log.error("USER_NOT_EXIST ae",ae);
            return new Result(ResultCode.USER_LOGIN_ERROR);
        } catch (Exception e) {
            log.error(String.valueOf(e));
            return new Result(ResultCode.USER_LOGIN_ERROR);
        }


    }

    @PostMapping("/register")
    public Result register(@RequestBody User user) {
        log.info(String.valueOf(user));
        Integer register = userService.addUser(user);
        return Result.SUCCESS("注册成功");
    }

    @GetMapping("/{pageSize}/{pageNumber}")
    public Result userPage(@PathVariable("pageSize") Integer pageSize,
                           @PathVariable("pageNumber") Integer pageNumber,
                           User user) {
//        User user = new User();
//        user.setUsername(username);
//        user.setEmail(email);
        log.info(String.valueOf(user));
        PagingResult userPage = userService.findUserPage(pageSize, pageNumber, user);
        return Result.SUCCESS(userPage);
    }

    @GetMapping({"/{id}", "/personal/{id}"})
    public Result getUser(@PathVariable("id") Integer id) {
        User user = new User();
        user.setId(id);
        return Result.SUCCESS(userService.findUser(user));
    }

    @PutMapping({"/", "/personal"})
    public Result updateUser(User user,
                             @RequestParam(value = "file", required = false) MultipartFile file) {
        log.info(String.valueOf(user));
        if (file != null) {
            String fileName = file.getOriginalFilename();
            user.setAvatar(fileName);
            File avater = new File(fileName);
            try {
                file.transferTo(avater);
                log.info("上传成功");
            } catch (IOException e) {
                log.error(e.toString(), e);
                return new Result(ResultCode.FILE_ACCEPT_ERROR);
            }
        }
        if (user != null) {
            userService.updateUser(user);
        } else {
            return new Result(ResultCode.FILE_ACCEPT_ERROR);
        }

        return Result.SUCCESS();
    }

    @PutMapping("/{id}/status/{status}")
    public Result updateUserStatus(@PathVariable("id") Integer id,
                                   @PathVariable("status") Boolean status) {
        User user = new User();
        user.setId(id);
        user.setStatus(status);
        log.info(String.valueOf(user));
        Integer setStatus = userService.updateUser(user);
        return Result.SUCCESS(setStatus);
    }

    @RequiresRoles("admin")
    @DeleteMapping("/{id}")
    public Result deleteUser(@PathVariable("id") Integer id) {
        Integer delete = userService.deleteUser(id);
        return Result.SUCCESS();
    }

    @PostMapping("/")
    public Result addUser(User user) {
        Integer add = userService.addUser(user);
        return Result.SUCCESS();
    }

    @GetMapping("unauthorized")
    @ResponseStatus(code = HttpStatus.OK,reason = "20")
    public Result unauthorized() {
        return new Result(ResultCode.PERMISSION_UNAUTHORISE);
    }

    @GetMapping("unLogin")
    //@ResponseStatus(code = HttpStatus.OK,reason = "20")
    public ResponseEntity unLogin() {
        return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        //return new Result(ResultCode.USER_NOT_LOGGED_IN);
    }
}
